/***************************************************************************
 *   Copyright (C) 2007 by Andreas Theofilu                                *
 *   andreas@TheoSys.at                                                    *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation version 3 of the License.                *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#include "helper.h"

int ComputeSize (int OrgLen, int NewLen, int OrgSize)
{
double OLen, NLen, OSize, zw;

	OLen = (double)OrgLen;
	NLen = (double)NewLen;
	OSize = (double)OrgSize;

	zw = (NLen / OLen) * OSize;
	return (int)zw;
}

void date_int (int *day, int *mon, int *year, long date)
{
	if (day == NULL || mon == NULL || year == NULL || date <= 10000L)
	   return;

	*year = (int)(date / 10000);
	*day = (int)(date % 100);
	*mon = (int)((date % 10000) - *day) / 100;
}

double integer (double zahl)
{
long zw;
double ret;

	zw = (long)zahl;
	ret = (double)zw;
	return ret;
}

double round (double zahl, int prez)
{
double divi;
long zw;

	divi = pow (zahl + 0.5,(double)prez);
	zw = (zahl + 0.5) * divi;
	return (double)zw / divi;
}

long get_date (char *sdate)
{
int tag,mon,year,i,j,pos,len,punkt;
char zw[21];
char *beg,*end;

	if (sdate == NULL || strlen (sdate) < 6)
	   return -1L;

	if (strchr (sdate,'.') != NULL)
	   punkt = 1;
	else
	   punkt = 0;

	if (punkt && strlen (sdate) < 8)
	   return -1L;

	tag = mon = year = 0;
	pos = 0;
	beg = sdate;

/* Tag */
	if (punkt)
	{
	   if ((end = strchr (beg,'.')) == NULL)
	      return -1L;

	   j = end - beg;

	   if (j > 2)
	      return -1L;

	   len = j;
	   beg = end;
	}
	else
	   len = 2;

	strncpy (&zw[0],sdate,len);
	zw[len] = 0;
	tag = atoi (zw);
	pos = len;

/* Monat */
	if (!isdigit (*(sdate+pos)))
	{
	   beg++;
	   pos++;
	}

	if (punkt)
	{
	   if ((end = strchr (beg,'.')) == NULL)
	      return -1L;

	   j = end - beg;

	   if (j > 2)
	      return -1L;

	   len = j;
	   beg = end;
	}
	else
	   len = 2;

	strncpy (&zw[0],sdate+pos,len);
	zw[len] = 0;
	mon = atoi (zw);
	pos += len;

/* Jahr */
	if (!isdigit (*(sdate+pos)))
	   pos++;

	beg = sdate+pos;
	i = strlen (beg);

	if (i != 4 && i != 2)
	   return -1L;

	year = atoi (beg);

/* Überprüfung */

	if (tag == 0 && mon == 0 && year == 0)
	   return 0L;

	if (mon < 1 || mon > 12)
	   return -1L;

	if (year < 100)
	{
	   if (year < 50)
	      year += 2000;
	   else
	      year += 1900;
	}

	if ((year % 4) == 0)
	   MonLeiste[1] = 29;
	else
	   MonLeiste[1] = 28;

	if (tag < 1 || tag > MonLeiste[mon-1])
	   return -1L;

	return (long)year * 10000L + ((long)mon * 100L) + (long)tag;
}

long get_gebos_date (char *sdate, int kenn)
{
int tag,mon,year,i,j,pos,len,punkt;
char zw[21];
char *beg,*end;

	if (sdate == NULL)
	   return -1L;

	if (!kenn)
	{
	   if (strlen (sdate) < 6)
	      return -1L;
	}
	else if (strlen (sdate) < 4 && strlen (sdate) > 0 && kenn)
	      return -1L;
	else if (strlen (sdate) == 0 && kenn)
	      return 0L;		/* Kein Datum */

	if (strchr (sdate,'.') != NULL)
	   punkt = 1;
	else
	   punkt = 0;

	if (!kenn)
	{
	   if (punkt && strlen (sdate) < 8)
	      return -1L;
	}
	else
	{
	   if (punkt && strlen (sdate) < 5)
	      return -1L;
	}

	tag = mon = year = 0;
	pos = 0;
	beg = sdate;

/* Tag */
	if (!kenn)
	{
	   if (punkt)
	   {
	      if ((end = strchr (beg,'.')) == NULL)
		 return -1L;

	      j = end - beg;

	      if (j > 2)
		 return -1L;

	      len = j;
	      beg = end;
	   }
	   else
	      len = 2;

	   strncpy (&zw[0],sdate,len);
	   zw[len] = 0;
	}
	else
	{
	   strcpy (&zw[0], "01");
	   len = 0;
	}

	tag = atoi (zw);
	pos = len;

/* Monat */
	if (!isdigit (*(sdate+pos)))
	{
	   beg++;
	   pos++;
	}

	if (punkt)
	{
	   if ((end = strchr (beg,'.')) == NULL)
	      return -1L;

	   j = end - beg;

	   if (j > 2)
	      return -1L;

	   len = j;
	   beg = end;
	}
	else
	   len = 2;

	strncpy (&zw[0],sdate+pos,len);
	zw[len] = 0;
	mon = atoi (zw);
	pos += len;

/* Jahr */
	if (!isdigit (*(sdate+pos)))
	   pos++;

	beg = sdate+pos;
	i = strlen (beg);

	if (i != 4 && i != 2)
	   return -1L;

	year = atoi (beg);

/* Überprüfung */

	if (tag == 0 && mon == 0 && year == 0)
	   return 0L;

	if (mon < 1 || mon > 12)
	   return -1L;

	if (year < 100)
	{
	   if (year < 50)
	      year += 2000;
	   else
	      year += 1900;
	}

	if ((year % 4) == 0)
	   MonLeiste[1] = 29;
	else
	   MonLeiste[1] = 28;

	if ((tag < 1 || tag > MonLeiste[mon-1]) && tag != 32)
	   return -1L;

	return (long)year * 10000L + ((long)mon * 100L) + (long)tag;
}

void set_feb (int year)
{
	if (year == 1900 || year == 2100)
	{
	   MonLeiste[1] = 28;
	   return;
	}

	if (year % 4)
	   MonLeiste[1] = 28;
	else
	   MonLeiste[1] = 29;
}

long DateToDay (long date)
{
int day, mon, year, jahre, sj, i;
long tage;

	if (date <= 0L)
	   return 0L;

	date_int (&day, &mon, &year, date);

	if (day <= 0 || mon <= 0 || year <= 0)
	   return 0L;

	jahre = (year >= 1900) ? year - 1900 : year;
	sj = 0;

	if (jahre < 1)
	   tage = 0L;
	else
	{
	   tage = ((long)jahre - 1L) * 365L;
	   sj = (jahre - 1) / 4;
	}

	tage += (long)sj;
	set_feb (year);

	for (i = 0; i < (mon-1); i++)
	   tage += (long)MonLeiste[i];

	tage += (long)day;
	return tage;
}

long DayToDate (long days)
{
int jahr, mon, day, i, j;

	if (days <= 0L)
	   return 0L;

	if (days >= 365)
	{
	   jahr = (int)(days / 365L);
	   mon = (int)(days - (((long)jahr * 365L) + ((long)jahr / 4L)));

	   if (mon == 0)
	      mon = 1;

	   jahr++;
	}
	else
	{
	   jahr = 0;
	   mon = days;
	}

	set_feb (jahr + 1900);
	i = j = 0;

	while (i < mon)
	{
	   i += MonLeiste[j];
	   j++;

	   if (i < mon && j >= 12)
	      j = 0;
	}

	i -= MonLeiste[j-1];
	day = mon - i;
	mon = j;

	return (long)(jahr+1900) * 10000L + ((long)mon * 100L) + (long)day;
}

long make_date (int day, int mon, int year)
{
	if (year < 1900)
	   year += 1900;

	if (year > 9999)
	   return 0L;

	return (long)year * 10000L + ((long)mon * 100L) + (long)day;
}

char *PointNumber (double Zahl, int prec, char *ret)
{
char buf[128], hv0[128];
int i, j, a, count, maxlen;
BOOL flag;
char *p;

	if (ret == NULL)
	   return NULL;

	// Ist Zahl < 0.0?

	if (Zahl < (double)0.0)
	{
	   *ret = '-';			// dann Minus setzen
	   j = 1;
	}
	else
           j = 0;

	sprintf (buf, "%%%d.%df", 2+prec, prec);

	// Wenn Zahl negativ dann Positiv machen

	if (Zahl < (double)0.0)
	   Zahl = Zahl * (-1.0);

	sprintf (hv0, buf, Zahl);

	// Interpunktion in die Zahl setzen

	i = strlen (hv0);
	maxlen = sizeof(hv0);
	p = hv0;
	a = 0;
	flag = FALSE;
	count = (i - prec - 1) % 3;

	if (count == 0)
	   count = 3;

	while (a < i && a < maxlen && j < maxlen)
	{
	   if (*p == '.')
	   {
              *p = ',';
	      flag = TRUE;
           }

	   if (count == 0 && a > 0 && !flag)
	   {
	      ret[j] = '.';
	      j++;
	      count = 3;
	   }

	   ret[j] = *p++;
	   j++;
	   a++;
	   count--;
	}

	ret[j] = 0;
	return ret;
}
